#include "hunter.h"
#include "Util/logger.h"
#include "json.h"
#include "ConfigApi.h"
#include "ProtocolApi.h"
#include "MediaApi.h"
#include "StreamApi.h"
#include "frame_common.h"
#include "StreamPushServer.h"
#include "recordServer.h"
#include "RtspServer.h"
#include "ConfigServer.h"
#include "UpgraderServer.h"
#include "RebootServer.h"
#include "FocusServer.h"
#include "InputSourceManager.h"
#include "DeviceStatusServer.h"
#include "hidDeviceManager/HidDeviceManager.h"
#include "DeviceManager.h"
#include "ConfigManager.h"

using namespace Fdt;
using namespace Protocol;
using namespace Media;
using namespace ConfigApi;
using namespace Stream;
using namespace FrameCommon;


void InstallProtocolApi(){
    ConfigServer::instance();
    StreamPushServer::instance();
    recordServer::instance();
    RtspServer::instance();
    UpgraderServer::instance();
    RebootServer::instance();
    FocusServer::instance();
    InputSourceManager::instance();
    DeviceStatusServer::instance();

    HidDeviceManager::Instance();
    DeviceManager::Instance();
    ConfigManager::Instance();
}

class CDeviceChannelFinder:public MediaChannelFinder{
public:
    CDeviceChannelFinder():MediaChannelFinder(){}
    MediaChannel::Ptr GetChannel(int video, int audio){
        return IMediaInterface::GetInstance()->GetMediaChannel(video, audio);
    }
    ~CDeviceChannelFinder(){}
};

class CDevicePlayCreater:public StreamPlayCreater{
public:
    virtual StreamPlayer::Ptr CreateStreamPlayer(const std::string& stream_url, 
        bool isRtspTcp = false){
        return Stream::IStreamInterface::GetInstance()->CreateStreamPlayer(stream_url, isRtspTcp);
    }
};

void CHunter::Start(){
    Logger::Instance().add(std::make_shared<ConsoleChannel>());
    Logger::Instance().setWriter(std::make_shared<AsyncLogWriter>());

    StreamPlayCreater::Ptr creater = std::make_shared<CDevicePlayCreater>();
    IMediaInterface::GetInstance()->SetStreamPlayCreater(creater);

    IProtocolInterface::GetInstance()->Init();
    InstallProtocolApi();

    MediaChannelFinder::Ptr mediaFinder = std::make_shared<CDeviceChannelFinder>();
    Stream::IStreamInterface::GetInstance()->SetMediaChannelFinder(mediaFinder);


    Stream::IStreamInterface::GetInstance()->Start();
    IMediaInterface::GetInstance()->Start();
    IProtocolInterface::GetInstance()->Start();

    //test
    // IProtocolInterface::GetInstance()->AuditoryworksRegistRequestRpc("Reboot", [](const Json::Value& req, Json::Value& res, std::string& errinfo){
    //     tracef(" Auditoryworks request Reboot comming ");
    //     errinfo = "device busy !!!";
    //     return false;
    // });

    //测试
    // MediaChannel::Ptr channel = IMediaInterface::GetInstance()->GetMediaChannel(0, 0);
    // auto result = channel->Start(123, [](const FrameCommon::Frame::Ptr& frame){
    //     tracef("frame  come on  codec id %d, data size %d, pts %llu\n", frame->codecId(),
    //          frame->size(), frame->pts());
    // });

    //测试文件上传
    // IProtocolInterface::GetInstance()->HttpUploadFile("http://192.168.16.59/api/upload", "/mnt/sd/RecordFile/mainstream/2023-08-21/07-33-45.mp4", 
    //     [](const Fdt::SockException &ex){
    //         std::cout<<"HttpUploadFile done "<<ex.what()<<endl;
    //     });
    
    //测试https
    // tracef(" debug 111111111");
    // IProtocolInterface::GetInstance()->SendHttpRequest("https://www.baidu.com",  "GET", 
    //     		"", [](const Fdt::SockException &ex, const std::string& response){
    //                 std::cout<<" test https res "<<response<<endl;
    //             });
    // tracef(" debug 22222222");


    // auto result_cb = [](const Fdt::SockException &ex){
    //     printf("!!!!!!!!!!! %s\n", ex.what());
    // };
    // std::function<void (void)> stop_func;
    // int progress = 0;
    // printf("11111111111111\n");
    // IProtocolInterface::GetInstance()->HttpDownloadFile("http://neartune-1320249760.cos.ap-shanghai.myqcloud.com/dynamic/01HDGBTXG5W46ZPJQ4N29V1F7J/gg2.mp4",
    //         "/mnt/media/gg2.mp4", 
	// 		result_cb, 
    //         progress,
	// 		stop_func);

    // std::this_thread::sleep_for(std::chrono::seconds(3));
    // printf("222222222222\n");
    // stop_func();
    // printf("33333333\n");
    // std::this_thread::sleep_for(std::chrono::seconds(3));
    // printf("444444444444\n");
    // return;

    return;
}

void CHunter::Stop(){
    Stream::IStreamInterface::GetInstance()->Stop();
    // IMediaInterface::GetInstance()->Stop();
    // IProtocolInterface::GetInstance()->Stop();
}